#include "ET++.ph"
#include "Converter.h"

#include "Class.h"
#include "Port.h"
#include "DevBitmap.h"
#include "Picture.h"
#include "PictPort.h"
#include "String.h"
#include "Data.h"
#include "HexFilter.h"
#include "TypeMatcher.h"

static const Symbol cDocTypeEpsf("EPSF");
static TypeMatcher matcher1(cDocTypeEpsf, "epsf", "%!PS-Adobe-3.0 EPSF-3.0", TRUE);
static TypeMatcher matcher2(cDocTypeEpsf, "epsf", "%!PS-Adobe-2.0 EPSF-1.2", TRUE);

//---- EpsfConverter -----------------------------------------------------------

class EpsfConverter : public Converter {
public:
	MetaDef(EpsfConverter);
	EpsfConverter()
		{ }
	const char *AsString()
		{ return "Encapsulated PostScript"; }
	Object *Convert(Data *data, Class *want);
	bool CanConvert(Data *data, Class *want)
		{ return data->Type() == cDocTypeEpsf && want == Meta(Picture); }
};

NewMetaImpl0(EpsfConverter,Converter);

Object *EpsfConverter::Convert(Data *data, Class*)
{
	IStream is(data->GetStreamBufForReading(), 0, TRUE);
	float v1, v2;
	char line[300];
	int llx, lly, urx, ury;
	Bitmap *bm= 0;
	int w, h, d, l;
	Rectangle r;
	PictPort *pp;
	Picture *pict;

	is.getline(line, 300);
	if (sscanf(line, "%%!PS-Adobe-%f EPSF-%f", &v1, &v2) != 2)
		return 0;

	pict= new Picture;
	pp= new PictPort(pict);
	pp->GiveHint(eHintEPSFStart, 0, 0);

	while (is.getline(line, 300)) {
		if (sscanf(line, "%%%%BoundingBox:%d%d%d%d", &llx, &lly, &urx, &ury) == 4) {
			r.extent.x= urx-llx;
			r.extent.y= ury-lly;
			r.origin= 1; // ???
		
			pp->GiveHint(55, 0, 0);
			pp->GiveHint(eHintPostScript, -1,
				form("%f %f scale\n",
					(float)r.extent.x/(float)(urx-llx),
				       -(float)r.extent.y/(float)(ury-lly)));
			pp->GiveHint(eHintPostScript, -1,
				form("%d %d translate\n", -llx, -ury));
			pp->GiveHint(55559, -1, "name");
			continue;
		}
		if (sscanf(line, "%%%%ImageWidth:%d", &w) == 1)
			continue;
		if (sscanf(line, "%%%%ImageHeight:%d", &h) == 1)
			continue;
		if (sscanf(line, "%%%%ImageDepth:%d", &d) == 1)
			continue;
		if (sscanf(line, "%%%%BeginImage:%d", &l) == 1
			|| sscanf(line, "%%%%BeginPreview: %d %d %d %d", &w, &h, &d, &l) == 4) {
		
			bm= new Bitmap(Point(w, h), d);
			BitmapInfo bi(Point(w, h), 1, 1);
		
			is.Push(new HexDecoder("%%EndPreview"));
			bm->GetDevBitmap()->ReadData(&bi, is);
			is.Pop();

			break;
		}
	}
	if (bm)
		pp->ShowBitmap(gInkBlack, r, bm);
	else
		pp->StrokeRect(gInkBlack, 2, r);
	pp->GiveHint(eHintEPSFEnd, 0, 0);
	SafeDelete(pp);
	return pict;
}

